/*
 * Copyright 2010-2013 Bornil Photography
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package main.java.net.bornil.controller.event;

import java.util.ArrayList;
import java.util.List;

import main.java.net.bornil.db.entity.Event;
import main.java.net.bornil.db.service.EventDao;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * @author MaMuN
 * @since 2012/08/25
 */
@Controller
@RequestMapping("/event")
public class EventMgmtController {
    private static Logger logger = Logger.getLogger(EventMgmtController.class.getName());

    @Autowired
    private EventDao eventService;

    /**
     * Name of the object that holds all information of event model
     */
    private static final String MODEL_EVENT = "event";

    /**
     * Holds list of events displayed in the event management screen as a result
     * of search or modify event.
     */
    private static final String MODEL_EVENT_LIST = "eventList";

    /**
     * Default handler for the request with <code>/event</code>. This handler
     * loads the initial event management page.
     * 
     * @param model
     *            Default model object
     * @return view URL
     */
    @RequestMapping(method = RequestMethod.GET)
    public String get(Model model) {
        // For initializing the search form
        model.addAttribute(MODEL_EVENT, new Event());
        // Displaying all created events
        model.addAttribute(MODEL_EVENT_LIST, eventService.getEvents());
        return "event/eventMgmt";
    }

    /**
     * Searches an existing event
     * 
     * @param event
     *            Event model with event id to search
     * @param result
     *            Used for displaying model validation result to the client
     * @param model
     *            Model object to hold fetched values
     * 
     * @return Final view to be rendered.
     */
    @RequestMapping(value = "/eventSearch", method = RequestMethod.POST)
    public String searchEvent(@ModelAttribute(MODEL_EVENT) Event event, BindingResult result, Model model) {

        // TODO :: Ques: What is the better way to handle validation?
        if (event.getEvtId() == null || event.getEvtId() == 0) {
            result.rejectValue("evtId", "err.required", new String[] { "evtId" }, "");
            return "event/eventMgmt";
        }

        Event evt = eventService.getEvent(event.getEvtId());
        if (evt.isNew()) {
            result.reject("err.notFound", new String[] { "Event" }, "Default");
        } else {
            List<Event> list = new ArrayList<Event>();
            list.add(evt);
            model.addAttribute(MODEL_EVENT_LIST, list);
        }
        return "event/eventMgmt";
    }

    /**
     * Loads an empty form to create new event
     * 
     * @param model
     *            Empty event model
     * 
     * @return Path of new event creation view
     */
    @RequestMapping(value = "/newEvent")
    public String newEvent(Model model) {
        // For initializing the search form
        model.addAttribute(MODEL_EVENT, new Event());
        return "event/eventForm";
    }

    /**
     * Loads event that will be modified
     * 
     * @param evtId
     *            ID of the event to be modified
     * @param model
     *            Model object to store fetched event information
     * 
     * @return Final view to be rendered
     */
    @RequestMapping("/editEvent/{evtId}")
    public String editEvent(@PathVariable("evtId") int evtId, Model model) {
        model.addAttribute(MODEL_EVENT, eventService.getEvent(evtId));
        return "event/eventForm";
    }

    /**
     * Handles event creation and update.
     * 
     * @param event
     *            Event entity with data to be added or modified
     * @param result
     *            Used for displaying model validation result to the client
     * @return Final view to be rendered.
     */
    @RequestMapping(value = "/saveEvent", method = RequestMethod.POST)
    public String saveEvent(@ModelAttribute(MODEL_EVENT) Event event, BindingResult result, Model model) {
        if (logger.isDebugEnabled()) {
            logger.debug("Event ID: " + event.getEvtId());
        }

        if (event.isNew()) {
            eventService.createEvent(event);
        } else {
            eventService.updateEvent(event);
        }
        model.addAttribute(MODEL_EVENT_LIST, eventService.getEvents());
        return "event/eventMgmt";
    }
}
